#include <iostream>
#include "Util.h"

using namespace std;

Util* Util::instant;

Util::Util()
{
	this->instant = NULL;
}

Util::~Util()
{
}


Util* Util::getInstant()
{
	if ( instant == NULL )
		instant = new Util();
	return instant;
}

//Check exist file?
int Util::isExist(char* filename)
{
	FILE* file = fopen(filename, "r");
	if(file)
	{
		fclose(file);
		return 1;
	}
	return 0;
}

//cut space before of string
char* Util::cutSpaceBefore ( char * str )
{
	//copy
	char* temp_str = new char[ strlen ( str )];
	strcpy ( temp_str, str );

	while ( temp_str[0] == ' ' )
	{
		for (int i = 0; i < strlen( temp_str ) - 1; i++)
			temp_str[i] = temp_str[i + 1];
		temp_str[strlen( temp_str ) - 1] = '\0';
	}
	return temp_str;
}

//convert char ABCDF to number
int Util::switchCharToNumver ( char ch )
{
	switch (ch)
	{
	case 'A':
	case 'a':
		return 10;
	case 'B':
	case 'b':
		return 11;
	case 'C':
	case 'c':
		return 12;
	case 'D':
	case 'd':
		return 13;
	case 'E':
	case 'e':
		return 14;
	case 'F':
	case 'f':
		return 15;
	default:
		return (ch - '0');
	}
}

//Ox1006 -> 6 not use 0x1 only conver 006
int Util::convertHexToDec (char* hec )
{
	int a2, a1, a0;
	a2 = switchCharToNumver ( hec[3] );
	a1 = switchCharToNumver ( hec[4] );
	a0 = switchCharToNumver ( hec[5] );
	
	return ( a2*16*16 + a1*16 + a0 );
}

//replace a char in str
char* Util::replaceChar ( char* str, char ch, char ch_replace )
{
	char* str_re = new char[ strlen ( str ) ];
	strcpy ( str_re, str );
	for ( int i = 0; i < strlen ( str_re ); i++ )
				if ( str_re[i] == ch )	
			str_re[i] = ch_replace;	
	return str_re;
}

//convert Dec to char
char* Util::convertDecToChar ( int num )
{
	if ( num == 0 )
	{
		char* str = "0";
		return str;
	}
	int n = num;
	int count = 0;
	int _array[20];
	while ( n != 0 )
	{
		_array[count] = n % 10;
		n /= 10;
		count++;
	}
	
	char* str = new char[count];
	for ( int i = count - 1; i >= 0; i-- )
		str[count - i - 1] = _array[i] + '0';
	str[count] = '\0';
	return str;
}

//get image name of sprite
char* Util::getImageNameWithExtent ( char* spriteName )
{
	char lineOrigin[200], _temp[200], tempImageName[255], imageName[50];	
	char *line;

	FILE *fIn = fopen( spriteName, "r");
	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << spriteName;
		return "";
	}

	while ( !feof ( fIn ) )
	{		
		fgets( lineOrigin, sizeof( lineOrigin ),fIn );
		line = Util::getInstant()->cutSpaceBefore ( lineOrigin );
				
		if ( line[0] == 'I' && line[1] == 'M' && line[2] == 'A' && line[3] == 'G' && line[4] == 'E' )
		{		
			int w, h;
			sscanf(&line[0], "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%d" "%s" "%d", &_temp, &_temp, &tempImageName, &_temp, &_temp, &_temp, &_temp, &_temp, &w, &_temp, &h);
			
			//tempImageName with ".../imageName.png"
			//cut "" 

			char temp[50]; 
			for (int i = strlen ( tempImageName ) - 2; i >= 0; i-- )
			{	
				if ( tempImageName[i] == '\\' )
				{
					temp[strlen ( tempImageName ) - 2 - i] = '\0';
					break;
				}
				temp[strlen ( tempImageName ) - 2 - i] = tempImageName[i];
			}

			for (int i = strlen ( temp ) - 1; i >= 0; i-- )
			{	
				
				imageName[strlen ( temp ) - 1 - i] = temp[i];
			}

			//cut .png
			imageName[strlen ( temp )] = '\0';			
			break;
		}

		memset ( lineOrigin, 0, sizeof ( lineOrigin ) );
		memset ( line, 0, sizeof ( line ) );
	}

	fclose ( fIn );

	char* name = new char[strlen (imageName)];
	strcpy (name, imageName);
	return name;
}

//get image name of sprite with non extend ex menu
char* Util::getImageName( char* spriteName )
{
	char* temp = getImageNameWithExtent ( spriteName );
	int lengh = strlen ( temp ) - strlen ( ".png" );
	char* name = new char [lengh];
	strcpy ( name, temp );
	name[lengh] = '\0';	
	return name;
}

//get size of image
Point Util::getImageSize ( char* spriteName )
{
	Point imageSize;
	char lineOrigin[200], temp[200];
	char *line;

	FILE *fIn = fopen( spriteName, "r");
	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << spriteName;		
		return imageSize;
	}

	while ( !feof ( fIn ) )
	{		
		fgets( lineOrigin, sizeof( lineOrigin ),fIn );
		line = Util::getInstant()->cutSpaceBefore ( lineOrigin );
				
		if ( line[0] == 'I' && line[1] == 'M' && line[2] == 'A' && line[3] == 'G' && line[4] == 'E' )
		{		
			int w, h;
			sscanf(&line[0], "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%d" "%s" "%d", &temp, &temp, &temp, &temp, &temp, &temp, &temp, &temp, &imageSize.x, &temp, &imageSize.y);
			break;
		}

		memset ( lineOrigin, 0, sizeof ( lineOrigin ) );
		memset ( line, 0, sizeof ( line ) );
		memset ( temp, 0, sizeof ( temp ) );
	}

	fclose ( fIn );

	return imageSize;
}

//get max module can
int Util::getModuleMax ( char* spriteName )
{
	char lineOrigin[200], temp[20], tempHex[10];
	char* line;
	int maxNum = -1, tempNum;

	
	FILE *fIn = fopen( spriteName, "r");
	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << spriteName;		
		return -1;
	}

	while ( !feof ( fIn ) )
	{		
		fgets( lineOrigin, sizeof( lineOrigin ),fIn );
		line = Util::getInstant()->cutSpaceBefore ( lineOrigin );

		if ( line[0] == 'M' && line[1] == 'D' )
		{
			sscanf(&line[0], "%s" "%s", &temp, &tempHex );
			tempNum = Util::getInstant()->convertHexToDec ( tempHex );
			if ( maxNum < tempNum )
				maxNum = tempNum;
		}

		if ( line[0] == '}' )
			break;

		memset ( lineOrigin, 0, sizeof ( lineOrigin ) );
		memset ( line, 0, sizeof ( line ) );
		memset ( temp, 0, sizeof ( temp ) );
		memset ( temp, 0, sizeof ( tempHex ) );
	}

	fclose (fIn);	
	return ( maxNum + 1 );
}

//get max frame can // return -1 if not exist
int Util::getFrameMax ( char* spriteName )
{
	char lineOrigin[200], temp[20], tempHex[10];
	char* line;
	int maxNum = -1, tempNum;

	
	FILE *fIn = fopen( spriteName, "r");
	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << spriteName;		
		return -1;
	}

	while ( !feof ( fIn ) )
	{		
		fgets( lineOrigin, sizeof( lineOrigin ),fIn );
		line = Util::getInstant()->cutSpaceBefore ( lineOrigin );

		if ( line[0] == '0' && line[1] == 'x' && line[2] == '2' )
		{
			sscanf(&line[0], "%s", &tempHex );
			tempNum = Util::getInstant()->convertHexToDec ( tempHex );
			if ( maxNum < tempNum )
				maxNum = tempNum;
		}

		if ( line[0] == '0' && line[1] == 'x' && line[2] == '3' ) //anim
			break;

		memset ( lineOrigin, 0, sizeof ( lineOrigin ) );
		memset ( line, 0, sizeof ( line ) );
		memset ( temp, 0, sizeof ( tempHex ) );
	}

	fclose (fIn);	
	return ( maxNum + 1 );
}

//get max anim can // return -1 if not exist
int Util::getAnimMax ( char* spriteName )
{
	char lineOrigin[200], temp[20], tempHex[10];
	char* line;
	int maxNum = -1, tempNum;

	
	FILE *fIn = fopen( spriteName, "r");
	if ( fIn == NULL )
	{
		cout << endl << "\nCan not read file: " << spriteName;		
		return -1;
	}

	while ( !feof ( fIn ) )
	{		
		fgets( lineOrigin, sizeof( lineOrigin ),fIn );
		line = Util::getInstant()->cutSpaceBefore ( lineOrigin );

		if ( line[0] == '0' && line[1] == 'x' && line[2] == '3' )
		{
			sscanf(&line[0], "%s", &tempHex );
			tempNum = Util::getInstant()->convertHexToDec ( tempHex );
			if ( maxNum < tempNum )
				maxNum = tempNum;
		}
		
		memset ( lineOrigin, 0, sizeof ( lineOrigin ) );
		memset ( line, 0, sizeof ( line ) );
		memset ( temp, 0, sizeof ( tempHex ) );
	}

	fclose (fIn);	
	return ( maxNum + 1 );
}